OverviewThe idea is to have 2 actions, one that execute the ExecuteAndWait action and another one that teminates the already running ExecuteAndWait action. The ExecuteAndWait action will needs to implement a Terminatable interface allowing it to be identified by the terminating action and hence be able to be informed to terminate itself through the terminate() method ( from Terminatable interface ). XWork.xml configurations<action name="longrunning" class="com.foo.frontend.action.test.LongRunningAction"> <interceptor-ref name="defaultStack"/> <interceptor-ref name="execAndWait"/> <result name="wait" type="freemarker">/WEB-INF/content/action/test/longrunning/status.ftl</result> <result name="error" type="freemarker">/WEB-INF/content/action/test/longrunning/terminated.ftl</result> <result name="success" type="freemarker">/WEB-INF/content/action/test/longrunning/success.ftl</result> </action> <action name="terminatelongrunning" class="com.foo.frontend.action.test.TerminateLongRunningAction"> <result name="success" type="freemarker">/WEB-INF/content/action/test/longrunning/terminatesuccess.ftl</result> </action> Action longruning will be the action executing the ExecuteAndWait action where as action terminatelongrunning will be the action to terminate the _ExecuteAndWait action. Terminatable interfacepublic interface Terminatable { public void terminate(); } ExecuteAndWait action wish to be informed about its termination such that it could ends itself gracefully should implement this interface. The ExecuteAndWait Actionpublic class LongRunningAction extends ActionSupport implements Terminatable { private boolean terminated=false; private int i=0; public String execute() { while( i++ < 100 ) { if( terminated ) { return ERROR; } try { Thread.sleep(1000); } catch( InterruptedException ie ) { // blah } } return SUCCESS; } public int getProgress() { return i; } public void terminate() { this.terminated = true; } } The ExecuteAndWait action is basically a conditional loop that loop indefintely until it's informed to ends itself by breaking the loop. The action to terminate ExecuteAndWait actionimport java.util.Map; import com.opensymphony.webwork.interceptor.BackgroundProcess; import com.opensymphony.webwork.interceptor.SessionAware; import com.opensymphony.xwork.ActionSupport; public class TerminateLongRunningAction extends ActionSupport implements SessionAware { private String name = "__execWaitlongrunning"; private Map session; public String execute() { BackgroundProcess bp = (BackgroundProcess) session.get( name ); if( bp==null || bp.getAction()==null || !(bp.getAction() instanceof Terminatable) ) { return ERROR; } Terminatable t = (Terminatable) bp.getAction(); t.terminate(); return SUCCESS; } public void setSession( Map session ) { this.session = session; } } This action terminates the ExecuteAndWait action simply informing it through the terminate() method. The freemarker pagesstatus.ftl <html> <head> <title>Please wait</title> <meta http-equiv="refresh" content="1;url=<@ww.url includeParams="all" />"/> </head> <body> Progress: ${Session['__execWaitlongrunning'].action.progress}% </body> </html> success.ftl <html> <body> Exited normally. </body> </html> terminated.ftl <html> <body> Terminated. </body> </html> termiantefailed.ftl <html> <body> Process didn't exist or something like that. </body> </html> terminatesuccess.ftl <html> <body> The background action was signalled to terminate. </body> </html> Special thanks to Lens that contributed this sollution in WebWork's forum |